/*
 * Copyright (C) 2012 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package com.gitee.l0km.xthrift.thrift.metadata;

import com.facebook.swift.codec.metadata.ThriftCatalog;
import com.facebook.swift.codec.metadata.ThriftFieldMetadata;
import com.facebook.swift.service.metadata.ThriftMethodMetadata;
import com.gitee.l0km.com4j.basex.doc.ClassCommentProvider;
import com.gitee.l0km.xthrift.base.metadata.DecoratorThriftFieldMetadata;
import com.gitee.l0km.xthrift.base.metadata.ErpcType;

import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

import static com.gitee.l0km.xthrift.base.doc.CommentProviderFactories.providerOf;
import static com.gitee.l0km.xthrift.base.doc.CommentProviderFactories.withValidFactory;

import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 重载{@link #getParameters()}方法,用{@link DecoratorThriftFieldMetadata}替换{@link ThriftFieldMetadata}
 * @author guyadong
 *
 */
@Immutable
public class DecoratorThriftMethodMetadata extends ThriftMethodMetadata
{
	private volatile AtomicReference<ClassCommentProvider>  commentProvider;
	private volatile AtomicReference<ImmutableList<String>> docs ;
    public DecoratorThriftMethodMetadata(String serviceName, Method method, ThriftCatalog catalog){
    	super(serviceName, method, catalog);
    }
    /**  将{@link ThriftFieldMetadata}转换为 {@link DecoratorThriftFieldMetadata}对象 */
	private final Function<ThriftFieldMetadata,ThriftFieldMetadata> 
		FIELD_TRANSFORMER = 
			new Function<ThriftFieldMetadata,ThriftFieldMetadata>(){
				@Nullable
				@Override
				public ThriftFieldMetadata apply(@Nullable ThriftFieldMetadata input) {
				    return (null == input || input instanceof DecoratorThriftFieldMetadata)  
				    		? input 
				    		: new DecoratorThriftFieldMetadata(input)
								.setJavadocCommentProvider(getCommentProvider())
								.setOwnedMethod(getMethod());
				}};
    @Override
    public List<ThriftFieldMetadata> getParameters()
    {
        return Lists.transform(super.getParameters(), FIELD_TRANSFORMER);
    }

	public ErpcType getErpcReturnType() {
		return ErpcType.getErpcType(super.getReturnType());
	}

	@Override
	public ImmutableList<String> getDocumentation() {
		// double checking
		if (docs == null) {
			synchronized (this) {
				if (docs == null) {
					ImmutableList<String> _docs = super.getDocumentation();
					if (withValidFactory()) {
						if (_docs == null || _docs.isEmpty()) {
							_docs = ImmutableList.copyOf(getCommentProvider().commentOfMethod(getMethod(), true));
						}
					}
					docs = new AtomicReference<>(_docs);
				}
			}
		}
		return docs.get();
	}
	
	private ClassCommentProvider getCommentProvider() {
		if (commentProvider == null) {
			synchronized (this) {
				if (commentProvider == null) {
					commentProvider = new AtomicReference<>(
							withValidFactory() ? providerOf(getMethod().getDeclaringClass()) : null);
				}
			}
		}
		return commentProvider.get();
	}
}
